let { foo, bar, abc } = { foo: "aaa", bar: "bbb" };
console.log(foo, bar, abc); // aaa bbb undefined

// 【对现有对象进行解构赋值】
let { keys, values } = Object;
let obj = {
  a: 1,
  b: 2,
  c: 3,
};
console.log(keys(obj), values(obj)); // [ 'a', 'b', 'c' ] [ 1, 2, 3 ]

// 【嵌套对象解构】

// 例子1
let o = {
  p: [
    "Hello",
    {
      y: "World",
    },
  ],
};

let {
  p, // 这里的p是变量，不是模式
  p: [x, { y }], // 这里的p是模式，不是变量
} = o;

console.log(p, x, y); // [ 'Hello', { y: 'World' } ] Hello World

// 例子2
let obj2 = {
  loc: {
    start: {
      line: 1,
      column: 5,
    },
  },
};

let {
  loc: {
    start: { line },
  },
} = obj2;

console.log(line); // 1

// 【嵌套赋值】
let o1 = {};
let arr = [];
// 这里对foo进行解构，然后将foo赋值给o1.prop，将bar赋值给arr[0]
({ foo: o1.prop, bar: arr[0] } = { foo: 1, bar: 2 });
console.log(o1, arr); // { prop: 1 } [ 2 ]

// 【对象解构默认值】
// 默认值生效的条件是，对象的属性值严格等于undefined。
let {
  s,
  t = 3,
  u = 4,
  v: V = "some",
  w = "default",
} = { s: 1, t: 2, w: undefined };
console.log(s, t, u, V, w); // 1 2 4 some default

// 数组本质上也是特殊的对象，因此可以对数组进行对象属性的解构。
let arr2 = [1, 2, 3];
let { 0: first, [arr2.length - 1]: last } = arr2;
console.log(first, last); // 1 3
